#ifndef __M_SERVER_H__
#define __M_SERVER_H__
#include <iostream>
#include <vector>
#include <string>
#include <cassert>
#include <cstring>
#include <ctime>
#include <functional>
#include <unordered_map>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <memory>
#include <typeinfo>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <sys/eventfd.h>
#include <sys/timerfd.h>

#define INF 0
#define DBG 1
#define ERR 2
#define LOG_LEVEL DBG

#define LOG(level, format, ...) do{\
        if (level < LOG_LEVEL) break;\
        time_t t = time(NULL);\
        struct tm *ltm = localtime(&t);\
        char tmp[32] = {0};\
        strftime(tmp, 31, "%H:%M:%S", ltm);\
        fprintf(stdout, "[%p %s %s:%d] " format "\n", (void*)pthread_self(), tmp, __FILE__, __LINE__, ##__VA_ARGS__);\
    }while(0)

#define INF_LOG(format, ...) LOG(INF, format, ##__VA_ARGS__)
#define DEBUG_LOG(format, ...) LOG(DBG, format, ##__VA_ARGS__)
#define ERR_LOG(format, ...) LOG(ERR, format, ##__VA_ARGS__)

#define BUFFER_DEFAULT_SIZE 1024
class Buffer
{
public:
    Buffer(int capacity = BUFFER_DEFAULT_SIZE) : _buffer(capacity), _read_index(0), _write_index(0)
    {
    }
    ~Buffer() {}

    // 起始地址
    char *Begin()
    {
        return &_buffer[0];
        // return &*_buffer.begin()；*_buffer.begin等同于_buffer[0]
    }

    // 获取当前写位置
    char *WritePosition()
    {
        return Begin() + _write_index;
    }

    // 获取前沿空闲空间大小
    uint64_t HeadIdleSize()
    {
        return _read_index;
    }

    // 获取后沿空闲空间大小
    uint64_t TailIdleSize()
    {
        return _buffer.size() - _write_index;
    }

    // 移动数据到最前面
    void movBuffer()
    {
        uint64_t index = 0;
        while (_write_index > _read_index)
        {
            _buffer[index++] = _buffer[_read_index++];
        }
        _read_index = 0;
        _write_index = index;
    }

    // 确保可写空间足够（移动+扩容）
    bool EnsureWriteSpace(int len)
    {
        if (TailIdleSize() >= len)
        {
            return true;
        }
        else if (HeadIdleSize() + TailIdleSize() >= len)
        { // 移动数据
            movBuffer();
            return true;
        }
        else
        { // 扩容
            // 如果小于_buffer的数组大小会缩容
            _buffer.resize(_write_index + len);
            return true;
        }
    }

    // 将写位置向后移动指定位置
    void MoveWriteOffset(uint64_t len)
    {
        _write_index += len;
    }

    // 获取当前读位置
    char *ReadPosition()
    {
        return Begin() + _read_index;
    }

    // 获取可读数据大小
    uint64_t ReadAbleSize()
    {
        return _write_index - _read_index;
    }

    // 将读位置向后移动指定位置
    void MoveReadOffset(uint64_t len)
    {
        _read_index += len;
    }

    // 写入数据
    void Write(const void *date, uint64_t len)
    {
        if(len==0){
            return;
        }
        EnsureWriteSpace(len);
        std::copy((char *)date, ((char *)date) + len, WritePosition());
    }

    void WriteAndPush(const void *date, uint64_t len)
    {
        Write(date, len);
        MoveWriteOffset(len);
    }

    // 将写入数据操作和移动_write_index操作合二为一

    void WriteString(const std::string &data)
    {
        Write(data.c_str(), data.size());
    }

    void WriteStringAndPush(const std::string &data)
    {
        WriteString(data);
        MoveWriteOffset(data.size());
    }

    // 当你有一个const引用或指针时，你保证不会修改通过这个引用或指针访问的对象。
    // 如果允许调用非const成员函数，那么这些函数可能会修改对象的状态，
    // 从而违反了const引用的初衷。
    // 成员函数和const
    // 非const成员函数：这些函数可以修改对象的成员变量，
    // 因此它们不能在const对象或const引用/指针上被调用。
    // const成员函数：这些函数保证不会修改对象的任何成员变量（除了那些被标记为mutable的）。因此，它们可以在const对象或const引用/指针上被安全地调用。
    void WriteBuffer(Buffer &buffer)
    {
        Write(buffer.ReadPosition(), buffer.ReadAbleSize());
    }

    void WriteBufferAndPush(Buffer &buffer)
    {
        WriteBuffer(buffer);
        MoveWriteOffset(buffer.ReadAbleSize());
    }

    // 读取数据
    void Read(void *buf, uint64_t len)
    {
        if (ReadAbleSize() >= len)
        {
            std::copy(ReadPosition(), ReadPosition() + len, (char *)buf); // 保证参数类型统一
        }
        else
        {
            printf("缓冲区中的数据小于%lld", len);
        }
    }

    // 将读取数据操作和移动_read_index操作合二为一
    void ReadAndPop(void *buf, uint64_t len)
    {
        Read(buf, len);
        MoveReadOffset(len);
    }

    std::string ReadAsString(uint64_t len)
    {
        std::string s;
        // 要先扩容
        s.resize(len);
        // Read((char*)s.c_str(),len);这样强转是非常不严谨的
        Read(&s[0], len);
        return s;
    }

    // 将读取数据操作和移动_read_index操作合二为一
    std::string ReadAsStringAndPop(uint64_t len)
    {
        std::string re = ReadAsString(len);
        MoveReadOffset(len);
        return re;
    }

    // CRLF换行
    char *FindCRLF()
    {
        // 也可以使用menchr()查找
        int index = _read_index;
        while (index < _write_index)
        {
            // std::cout<<index<<std::endl;
            if (_buffer[index] == '\n')
            {
                // std::cout<<&_buffer[index]-ReadPosition()<<std::endl;
                // std::cout<<_read_index<<std::endl;
                return &_buffer[index];
            }
            index++;
        }
        // std::cout<<index<<std::endl;
        // 如果没有读取到换行也不需要返回，因为这是一个不完整的请求
        // return nullptr;
    }

    // //读取一行数据
    // std::vector<char> GetLine(){
    //     //用string接受遇到\0会停止
    //     std::vector<char> line;
    //     char*pos=FindCRLF();
    //     if(pos!=nullptr){
    //         uint64_t len=pos-ReadPosition();
    //         line.resize(len);
    //         Read(&line[0],len+1);
    //     }

    //     return line;
    // }

    // 读取一行数据
    std::string GetLine()
    {
        // 用string接受遇到\0会停止

        char *pos = FindCRLF();
        uint64_t len = pos - ReadPosition();
        // std::cout<<len<<std::endl;
        // 只读len的话\n没有读进去
        return ReadAsStringAndPop(len + 1);
    }

    // 清理功能
    // 不需要使用_buffer.clear(),直接归零覆盖写
    void Clear()
    {
        _write_index = 0;
        _read_index = 0;
    }

private:
    std::vector<char> _buffer;
    uint64_t _read_index;  // 读偏移
    uint64_t _write_index; // 写偏移
};


// 套接字管理模块
class Socket
{
public:
    Socket(int fd = -1) : _sockfd(fd) {}
    ~Socket() {}

    int Fd()
    {
        return _sockfd;
    }
    // 创建套接字
    void CreateSocket()
    {
        _sockfd = socket(AF_INET, SOCK_STREAM, 0);
    }

    // 绑定地址信息
    void Bind(uint32_t port)
    {
        struct sockaddr_in sockin;
        sockin.sin_family = AF_INET;
        sockin.sin_addr.s_addr = INADDR_ANY;
        sockin.sin_port = port;
        socklen_t socklen = sizeof(sockin);
        bind(_sockfd, (struct sockaddr *)&sockin, socklen);
    }

    // 开始监听
    void Listen(int n)
    {
        listen(_sockfd, n);
    }

    // 向服务器发起连接
    void Connect(uint32_t port, std::string ip)
    {
        struct sockaddr_in sockin;
        sockin.sin_family = AF_INET;
        sockin.sin_addr.s_addr = inet_addr(ip.c_str());
        sockin.sin_port = port;
        socklen_t socklen = sizeof(sockin);
        int newfd = connect(_sockfd, (struct sockaddr *)&sockin, socklen);
        if (newfd = -1)
        {
            perror("connect");
        }
    }

    // 获取新连接
    int Accept()
    {
        struct sockaddr_in client;
        socklen_t clientlen;
        int newfd = accept(_sockfd, (struct sockaddr *)&client, &clientlen);

        return newfd;
    }

    // 接收数据
    ssize_t Recv(void*buffer, int n,int flag=0)
    {
        int sz = recv(_sockfd, buffer, n, flag);
        //DEBUG_LOG("RECV sz:%d",sz);
        if (sz <=0)
        {
            if (errno == EAGAIN || errno == EINTR) {
                return 0;
            }
            DEBUG_LOG("RECV FAILED!!");
            return -1;
        }
        return sz;
    }

    ssize_t NonBlockRecv(void *buf, size_t len) {
        return Recv(buf, len, MSG_DONTWAIT); // MSG_DONTWAIT 表示当前接收为非阻塞。
    }

    // 发送数据
    // ssize_t Send(void *data, int n,int flag=0)
    // {
    //     int sz=send(_sockfd, data, n, flag);
    //     if (sz<=0)
    //     {
    //         ERR_LOG("SEND FAIL:%s", strerror(sz));
    //         return -1;
    //     }
    //     return sz;
    // }

    ssize_t Send(const void *buf, size_t len, int flag = 0) {
            // ssize_t send(int sockfd, void *data, size_t len, int flag);
            ssize_t ret = send(_sockfd, buf, len, flag);
            //DEBUG_LOG("SEND RET:%d",ret);
            if (ret <0) {
                if (errno == EAGAIN || errno == EINTR) {
                    return 0;
                }
                DEBUG_LOG("SOCKET SEND FAILED!!");
                return -1;
            }
            return ret;//实际发送的数据长度
        }

    ssize_t NonBlockSend(void *buf, size_t len) {
        if (len == 0) return 0;
        return Send(buf, len, MSG_DONTWAIT); // MSG_DONTWAIT 表示当前发送为非阻塞。
    }


    // 关闭套接字
    void Close()
    {
        if (_sockfd != -1)
        {
            close(_sockfd);
        }
    }

    // 创建一个服务端连接
    bool CreateServer(uint32_t port)
    {
        // if (_sockfd != -1)
        //     return false;
        CreateSocket();
        Bind(port);
        Listen(10);
        return true;
    }

    // 创建一个客户端连接
    void CreateClient(uint32_t port, std::string ip)
    {
        // if(_sockfd!=-1)
        //     return;
        CreateSocket();
        Connect(port, ip);
    }

    // 设置套接字选项
    void setSockopt()
    {
        int val = 1;
        setsockopt(_sockfd, SOL_SOCKET, SO_REUSEADDR, (void *)&val, sizeof(int));
        val = 1;
        setsockopt(_sockfd, SOL_SOCKET, SO_REUSEPORT, (void *)&val, sizeof(int));
    }

    // 设置套接字非阻塞属性
    void Fcntl()
    {
        int fl = fcntl(_sockfd, F_GETFL);
        if (fl < 0)
        {
            perror("fcntl");
        }
        fcntl(_sockfd, F_SETFL, fl | O_NONBLOCK);
    }

private:
    int _sockfd;
};

class Poller;
class EventLoop;
// 事件管理
class Channel
{
private:
    int _fd;
    EventLoop *_loop;
    // Poller *_poller;
    uint32_t _events;  // 当前需要监控的事件
    uint32_t _revents; // 当前连接触发的事件
    using EventCallback = std::function<void()>;
    EventCallback _read_callback;  // 可读事件被触发的回调函数
    EventCallback _write_callback; // 可写事件被触发的回调函数
    EventCallback _error_callback; // 错误事件被触发的回调函数
    EventCallback _close_callback; // 连接断开事件被触发的回调函数
    EventCallback _event_callback; // 任意事件被触发的回调函数
public:
    // Channel(int fd = -1, Poller *poller = nullptr) : _fd(fd), _poller(poller), _events(0), _revents(0), _read_callback(nullptr), _write_callback(nullptr), _error_callback(nullptr), _close_callback(nullptr), _event_callback(nullptr) {}
    //~Channel();
    Channel(EventLoop *loop,int fd) : _fd(fd), _loop(loop), _events(0), _revents(0) {}
    //, _read_callback(nullptr), _write_callback(nullptr), _error_callback(nullptr), _close_callback(nullptr), _event_callback(nullptr) {}

    void SetReadCallback(const EventCallback &cb)
    {
        _read_callback = cb;
    }

    void SetWriteCallback(const EventCallback &cb)
    {
        _write_callback = cb;
    }

    void SetErrorCallback(const EventCallback &cb)
    {
        _error_callback = cb;
    }

    void SetCloseCallback(const EventCallback &cb)
    {
        _close_callback = cb;
    }

    void SetEventCallback(const EventCallback &cb)
    {
        _event_callback = cb;
    }

    void SetRevents(int revents)
    {
        _revents = revents;
    }

    int Fd()
    {
        return _fd;
    }

    uint32_t Events()
    {
        return _events;
    }

    uint32_t Revents()
    {
        return _revents;
    }

    // 当前是否可读
    bool ReadAble()
    {
        return _events & EPOLLIN;
    }

    // 当前是否可写
    bool WriteAble()
    {
        return _events & EPOLLOUT;
    }

    int getBit(int number)
    {
        int bitNum = 0;
        while ((number >>= 1) > 0)
        {
            bitNum++;
        }

        return bitNum;
    }

    // 启动读事件监控
    void EnableRead()
    {
        _events |= EPOLLIN;
        Update();
    }

    // 启动写事件监控
    void EnableWrite()
    {
        _events |= EPOLLOUT;
        Update();
    }

    // 关闭读事件监控
    void DisableRead()
    {
        if (ReadAble())
        {
            _events ^= EPOLLIN;
            Update();
        }
    }

    // 关闭写事件监控
    void DisableWrite()
    {
        if (WriteAble())
        {
            _events ^= EPOLLOUT;
            Update();
        }
    }

    // 关闭所有事件监控
    void DisableAl1()
    {
        _events = 0;
        Update();
    }

    // 错误关闭触发事件监控
    void DisTriggerAl1()
    {
        _revents = 0;
    }

    // 因为使用了_poller中的成员函数，使用不能在这里直接定义，类外定义
    // 移除监控
    void Remove();

    // 更新监控
    void Update();

    // 事件处理，一旦连接触发了事件，就调用这个函数，自己触发了什么事件如何处理自己
    void HandleEvent()
    {
        if (EPOLLIN & _revents)
        {
            if (_event_callback)
                _event_callback();
            if (_read_callback)
                _read_callback();
        }

        if (EPOLLOUT & _revents)
        {
            if (_event_callback)
                _event_callback();
            if (_write_callback)
                _write_callback();
        }
        if (EPOLLERR & _revents)
        {
            // ERR_LOG("_error_callback:%d",_fd);
            if (_event_callback)
                _event_callback();
            if (_error_callback)
                _error_callback();
        }
        if (EPOLLHUP & _revents)
        {
            // ERR_LOG("_close_callback:%d",_fd);
            if (_event_callback)
                _event_callback();
            if (_close_callback)
                _close_callback();
        }

        //     if ((_revents & EPOLLIN) || (_revents & EPOLLRDHUP) || (_revents & EPOLLPRI)) {
        //             /*不管任何事件，都调用的回调函数*/
        //             if (_read_callback) _read_callback();
        //         }
        //         /*有可能会释放连接的操作事件，一次只处理一个*/
        //         if (_revents & EPOLLOUT) {
        //             if (_write_callback) _write_callback();
        //         }else if (_revents & EPOLLERR) {
        //             if (_error_callback) _error_callback();//一旦出错，就会释放连接，因此要放到前边调用任意回调
        //         }else if (_revents & EPOLLHUP) {
        //             if (_close_callback) _close_callback();
        //         }
        //         if (_event_callback) _event_callback();
    }
};









#define MAX_EPOLLEVENTS 1024
class Poller {
    private:
        int _epfd;
        struct epoll_event _evs[MAX_EPOLLEVENTS];
        std::unordered_map<int, Channel *> _channels;
    private:
        //对epoll的直接操作
        void Update(Channel *channel, int op) {
            // int epoll_ctl(int epfd, int op,  int fd,  struct epoll_event *ev);
            int fd = channel->Fd();
            struct epoll_event ev;
            ev.data.fd = fd;
            ev.events = channel->Events();
            int ret = epoll_ctl(_epfd, op, fd, &ev);
            if (ret < 0) {
                ERR_LOG("EPOLLCTL FAILED!");
            }
            return;
        }
        //判断一个Channel是否已经添加了事件监控
        bool HasChannel(Channel *channel) {
            auto it = _channels.find(channel->Fd());
            if (it == _channels.end()) {
                return false;
            }
            return true;
        }
    public:
        Poller() {
            _epfd = epoll_create(MAX_EPOLLEVENTS);
            if (_epfd < 0) {
                ERR_LOG("EPOLL CREATE FAILED!!");
                abort();//退出程序
            }
        }
        //添加或修改监控事件
        void UpdateEvent(Channel *channel) {
            bool ret = HasChannel(channel);
            if (ret == false) {
                //不存在则添加
                //DEBUG_LOG("新加入的监听fd:%d", channel->Fd());
                _channels.insert(std::make_pair(channel->Fd(), channel));
                return Update(channel, EPOLL_CTL_ADD);
            }
            return Update(channel, EPOLL_CTL_MOD);
        }
        //移除监控
        void RemoveEvent(Channel *channel) {
            auto it = _channels.find(channel->Fd());
            if (it != _channels.end()) {
                _channels.erase(it);
            }
            Update(channel, EPOLL_CTL_DEL);
        }
        //开始监控，返回活跃连接
        void Poll(std::vector<Channel*> *active) {
            // int epoll_wait(int epfd, struct epoll_event *evs, int maxevents, int timeout)
            //DEBUG_LOG("_epfd:%d",_epfd);
            int nfds = epoll_wait(_epfd, _evs, MAX_EPOLLEVENTS, -1);
            if (nfds < 0) {
                if (errno == EINTR) {
                    return ;
                }
                ERR_LOG("EPOLL WAIT ERROR:%s\n", strerror(errno));
                abort();//退出程序
            }
            for (int i = 0; i < nfds; i++) {
                auto it = _channels.find(_evs[i].data.fd);
                assert(it != _channels.end());
                it->second->SetRevents(_evs[i].events);//设置实际就绪的事件
                active->push_back(it->second);
            }
            return;
        }
};




















using TaskFunc = std::function<void()>;
using ReleaseFunc = std::function<void()>;
//非活跃销毁任务管理
class TimerTask{
private:
    uint64_t taskid_;            // 任务编号,不是线程id
    int timeout_;                // 间隔时间
    TaskFunc task_;             // 需要执行的任务
    bool _canceled;     // false-表示没有被取消， true-表示被取消,通过设置标注位任务取消了，避免任务的执行
    ReleaseFunc _release; //用于删除TimerWheel中保存的定时器对象信息
public:
    TimerTask(uint64_t taskid, int timeout, TaskFunc task)
        : taskid_(taskid), timeout_(timeout), task_(task), _canceled(false)
    {}

    void SetRelease(const ReleaseFunc &cb) { _release = cb; }
    void Cancel() { _canceled = true; }
    // 时间到，对象被销毁时，执行任务
    ~TimerTask()
    {
        //DEBUG_LOG("执行任务");
        //如果不设置标注位限制，时间到达后，引用计数为0，依然会执行任务
        //如果任务对象提前被取消，则不执行任务
        if (_canceled == false) task_(); 
        //_release(); 
    }

    uint32_t DelayTime() { return timeout_; }
};
















//时间轮
class EventLoop;
class TimerWheel
{
private:
    int tick_;                                               // 滴答指针
    int capacity_;                                           // 表盘容量，也就是最多的延时时间
    std::vector<std::vector<std::shared_ptr<TimerTask>>> _wheel; // 时间轮
    std::unordered_map<int, std::weak_ptr<TimerTask>> _timers;   // 通过fd找到weak_ptr,方便判断和构造对象，使用weak_ptr因为引用计数不会增加
    // 可能会有多个线程同时操作_timers,对定时器进行添加或删除，产生线程安全问题，因此把所有对于定时器的操作放到同一个线程里面执行，这样不会有效率问题吗？

    // 以秒为单位滚动事件轮
    int _timerfd;
    EventLoop *_loop;
    std::unique_ptr<Channel> _timer_channel;

    // 创建事件通知fd
    static int CreatTimerfd()
    {
        int timerfd = timerfd_create(CLOCK_MONOTONIC, 0);
        return timerfd;
    }

    void ReadTimerfd()
    {
        u_int32_t message;
        int n = read(_timerfd, &message, 8);
        if (n < 0)
        {
            ERR_LOG("TIMERFD READ FAIL:%s", strerror(n));
            abort();
        }
    }

    // 时间轮滚动
    void RunTimerTask()
    {
        tick_++;
        if (_wheel[(tick_ + capacity_) % 60].size() > 0)
        {
            // 删除指针，引用计数为0的，自动调用析构函数执行任务
            _wheel[(tick_ + capacity_) % 60].clear();
        }
    }

    // 读取_timerfd数据+滚动时间轮
    void RunTimer()
    {
        ReadTimerfd();
        RunTimerTask();
    }

    bool TimerIsInLoop();
    void TimerQueueInLoop(std::function<void()> fc);

    // 添加定时器,这个函数是有线程安全问题的，定时器跟EventLoop是一对一的，那么就不允许被非对应的EvnntLoop线程执行
    // 为什么其它线程会进入到这个定时器里面执行这个函数，多线程执行流，67节21分
    void TimerAddInLoop(uint64_t taskid, int timeout, std::function<void()> task)
    {
        std::shared_ptr<TimerTask> st(new TimerTask(taskid, timeout, task));
        //DEBUG_LOG("添加任务：%d", taskid);
        // 加入时间轮中
        _wheel[(tick_ + timeout) % 60].push_back(st);
        // 加入哈希表中方便查找，使用weak_ptr因为引用计数不会增加
        _timers[taskid] = std::weak_ptr<TimerTask>(st);
    }

    // 刷新定时器
    void TimerRefreshInLoop(uint64_t taskid)
    {
        // 判断
        if (!HasTimer(taskid))
        {
            //std::cout << "请先添加任务" << std::endl;
            return;
        }
        // 通过fd找到weak_ptr,方便判断和构造对象
        std::shared_ptr<TimerTask> sdelay = _timers[taskid].lock();
        // 再次加入到时间轮当中
        _wheel[(tick_ + (sdelay->DelayTime())) % 60].push_back(sdelay);
    }

    // 取消定时任务
    void TimerCancelInLoop(uint64_t taskid)
    {
        //除了要删除taskid外，还要避免任务被执行   
        //_timers.erase(taskid);

        //删除TimerWheel中保存的定时器对象信息
        auto it = _timers.find(taskid);
        if (it != _timers.end()) {
            _timers.erase(it);
        }
        // 通过fd找到weak_ptr,构造shared_ptr，修改标志位，防止后续时间到时，任务依然被执行
        //PtrTask pt = it->second.lock();
        auto pt = it->second.lock();
        if (pt) pt->Cancel();
    }

public:
    TimerWheel(EventLoop *loop = nullptr)
        : tick_(0), capacity_(60), _wheel(capacity_), _timerfd(CreatTimerfd()), _loop(loop), _timer_channel(new Channel(loop,_timerfd))
    {
        _wheel.resize(60);
        
        //设置通知时间
        itimerspec timeout;
        timeout.it_value.tv_sec = 1; // 第一次超时时间，单位为秒
        timeout.it_value.tv_nsec = 0;
        timeout.it_interval.tv_sec = 1;  // 第一次超时后的超时时间
        timeout.it_interval.tv_nsec = 0; // 第一次超时后的超时时间
        timerfd_settime(_timerfd, 0, &timeout, nullptr);

        // 默认带一个this指针
        _timer_channel->SetReadCallback(std::bind(&TimerWheel::RunTimer, this)); // 设置读回调函数
        _timer_channel->EnableRead();                                            // 添加监控
    }

    // std::bind 需要指定对象的实例来调用非静态成员函数，因为它需要一个上下文（即对象实例）来执行该成员函数。
    // 在你的 TimerAdd 方法中，TimerAddInLoop 是一个非静态成员函数，因此需要与 TimerWheel 类的一个实例关联起来才能被调用。
    // 然而，你的 std::bind 调用中没有提供这个实例。这会导致编译错误，因为编译器不知道在哪个 TimerWheel 实例上调用 TimerAddInLoop。
    void TimerAdd(uint64_t taskid, int timeout, std::function<void()> task)
    {
        if (TimerIsInLoop())
        {
            TimerAddInLoop(taskid, timeout, task);
        }
        else
            TimerQueueInLoop(std::bind(&TimerWheel::TimerAddInLoop, this, taskid, timeout, task));
        // else TimerQueueInLoop(std::bind(TimerWheel::TimerAddInLoop,taskid,timeout,task));错误
    }

    void TimerRefresh(uint64_t taskid)
    {
        if (TimerIsInLoop())
        {
            TimerRefreshInLoop(taskid);
        }
        else
            TimerQueueInLoop(std::bind(&TimerWheel::TimerRefreshInLoop, this, taskid));
    }

    void TimerCancel(uint64_t taskid)
    {
        if (TimerIsInLoop())
        {
            TimerCancelInLoop(taskid);
        }
        else
            TimerQueueInLoop(std::bind(&TimerWheel::TimerCancelInLoop, this, taskid));
    }

    // 判断是否已经加入时间轮中
    bool HasTimer(uint64_t taskid)
    {
        auto num = _timers.begin();

        while (num != _timers.end())
        {
            if (num->first == taskid)
            {
                return true;
            }
            num++;
        }

        return false;
    }
};

//整合模块
class EventLoop
{
private:
    using Functor = std::function<void()>;
    std::thread::id _thread_id;              // 线程ID
    int _event_fd;                           // eventfd唤醒I0事件监控有可能导致的阻塞
    std::unique_ptr<Channel> _event_channel; // 管理_event_fd,用智能指针管理，loop释放时也能一起释放
    Poller _poller;                          // 进行所有描述符的事件监控
    std::vector<Functor> _tasks;             // 任务池
    std::mutex _mutex;                       // 实现任务池操作的线程安全
    TimerWheel *_wheel;                      // 事件轮
private:
    // 为什么在这里就能保证任务被自己对应的EventLoop线程执行
    // 执行任务池中的所有任务
    void RunAllTask(){
        //交换任务池中的任务
        std::vector<Functor> tasks;
        // 增加一个作用域，出了这个作用域锁自动释放
        // 创建一个互斥量的锁，并在构造时立即锁定它，然后在对象销毁时自动解锁。
        {
            std::unique_lock<std::mutex> unlock(_mutex);
            _tasks.swap(tasks);
        }

        // 为什么在这就是它自己的线程执行？
        for (auto &f : tasks)
        {
            f();
        }
    }

    // 如果CreateEventFd()函数不需要访问类的任何非静态成员变量，
    // 并且它的功能是与类无关的（例如，它只是一个辅助函数，用于创建一个事件文件描述符），
    // 那么你可以将其设置为static。这样，它就可以在没有类实例的情况下被调用。
    static int CreateEventFd(){
        int event_fd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
        return event_fd;
    }

    void ReadEventfd() {
            uint64_t res = 0;
            int ret = read(_event_fd, &res, sizeof(res));
            if (ret < 0) {
                //EINTR -- 被信号打断；   EAGAIN -- 表示无数据可读
                if (errno == EINTR || errno == EAGAIN) {
                    return;
                }
                ERR_LOG("READ EVENTFD FAILED!");
                abort();
            }
            return ;
        }
        void WeakUpEventFd() {
            uint64_t val = 1;
            int ret = write(_event_fd, &val, sizeof(val));
            if (ret < 0) {
                if (errno == EINTR) {
                    return;
                }
                ERR_LOG("WRITE EVENTFD FAILED!");
                abort();
            }
            return ;
        }

//     void ReadEventfd(){
//         uint64_t val;
//         // 写入或读出只能以8字节为单位
//         read(_event_fd, &val, 8);
//     }

//     void WeakUpEventfd(){
//         int val = 1;
//         write(_event_fd, &val, 8);
//     }

public:
    EventLoop()
        : _thread_id(std::this_thread::get_id()), _event_fd(CreateEventFd()), _event_channel(new Channel(this,_event_fd)), _wheel(new TimerWheel(this))
    {
        // 传this指针是因为函数内部会访问类的成员，方便在外部被调用时，也就能够使用,设置为static是因为它没有this指针
        _event_channel->SetReadCallback(std::bind(&EventLoop::ReadEventfd, this));
        _event_channel->EnableRead();
    }

    // 三步走--事件监控-》就绪事件处理-》执行任务,当没有事件来时，会阻塞在事件监控中，导致任务一直不被执行
    void Start(){
        while(1)
        {
            // 事件监控
            std::vector<Channel *> actives;
            _poller.Poll(&actives);
            // 就绪事件处理
            //有些需要保障线程安全的操作可能会压入任务队列中
            for (auto c : actives)
            {
                c->HandleEvent();
            }

            RunAllTask();
        }
    }

    // 判断当前线程是否为EventLoop对应的线程，this_thread
    bool IsInLoop(){
        return _thread_id == std::this_thread::get_id();
    }

    // 判断将要执行的任务是否处于当前线程中，如果是则执行，不是则压入队列。
    void RunInLoop(const Functor &cb){
        if (IsInLoop())
        {
            cb();
        }
        else
        {
            QueueInLoop(cb);
        }
    }

    // 将操作压入任务池
    void QueueInLoop(const Functor &cb){
        // 确保线程安全
        {
            std::unique_lock<std::mutex> unlock(_mutex);
            _tasks.push_back(cb);
        }
        // 防止_poller阻塞
        WeakUpEventFd();
    }

    // 添加/修改描述符的事件监控
    void UpdateEvent(Channel *channel){
        _poller.UpdateEvent(channel);
    }

    // 移除描述符的监控
    void RemoveEvent(Channel *channel){
        _poller.RemoveEvent(channel);
    }

    void TimerAdd(uint64_t taskid, int timeout, std::function<void()> task){
        _wheel->TimerAdd(taskid, timeout, task);
    }

    void TimerRefresh(uint64_t taskid){
        _wheel->TimerRefresh(taskid);
    }

    void TimerCancel(uint64_t taskid){
        _wheel->TimerCancel(taskid);
    }

    bool HasTimer(uint64_t taskid){
        return _wheel->HasTimer(taskid);
    }
};


class LoopThread{
private:
    /*用于实现_loop获取的同步关系，避免线程创建了，但是_loop还没有实例化之前去获取_loop*/
    std::mutex _mutex;//互斥锁
    std::condition_variable _cond;//条件变量，保障获取EventLoop时，一定不为nullptr
    EventLoop* _loop;//线程对应的EventLoop,保障是对应的线程创建，所以使用指针，先创建线程再创建EventLoop
    std::thread _thread;//创建的线程

private:
    // /*实例化 EventLoop 对象，唤醒_cond上有可能阻塞的线程，并且开始运行EventLoop模块的功能*/
    //创建线程对应的EventLoop
    void CreateEventLoop(){
        //使用局部变量，限制其生命周期随着线程销毁而销毁
        EventLoop loop;
        {
            std::unique_lock<std::mutex> lock(_mutex);
            _loop=&loop;
            //唤醒条件变量中所有等待的线程
            _cond.notify_all();
        }
        DEBUG_LOG("CREATE THREAD SUCCESS");
        //启动线程，里面有while（1）循环
        _loop->Start();
    }
public:
    /*创建线程，设定线程入口函数*/
    LoopThread():
    _loop(nullptr)
    ,_thread(std::thread(&LoopThread::CreateEventLoop,this))
    {}
    //~LoopThread(){}

    //有一个问题：我们如何确保获取loop时它不为nullptr，因为可能会有我们还没创建loop时，就有访问loop的情况出现
    //锁+条件变量
    //获取loop
    EventLoop* GetLoop(){
        EventLoop*loop;
        {
            std::unique_lock<std::mutex> lock(_mutex);
        // []：不捕获任何变量。
        // [=]：以值捕获所有外部变量。
        // [&]：以引用捕获所有外部变量。
        // [x]：仅以值捕获变量 x。
        // [&x]：仅以引用捕获变量 x。
        // [=, &x]：以值捕获所有外部变量，但以引用捕获 x。
        // [&, x]：以引用捕获所有外部变量，但以值捕获 x（注意这种用法较少见，因为它通常不是必要的）。
        //wait的第二变量为函数返回的bool值，只要为false则一直阻塞
            _cond.wait(lock,[&](){return _loop!=nullptr;});
            loop=_loop;
        }
        //DEBUG_LOG("GET LOOP");
        return loop;
    }
};


//为什么要用Loopthread*,而不能用LoopThread
//LoopThread 类中包含了不可移动（或不可复制）的成员变量 std::mutex 和 std::condition_variable。
//由于 LoopThread 类包含了不可移动的成员，编译器会隐式删除移动构造函数。这意味着你不能通过移动操作来传递或赋值 LoopThread 对象。
//std::vector<LoopThread>，那么每次向vector中添加元素时，都会复制或移动LoopThread对象
//管理loopd线程池模块
//需要考虑0个或多个从属线程的情况
class LoopThreadPool{
    EventLoop* _baseloop;//主EventLoop,当从属线程为0时，都由主Eventloop监控和处理所有事件
    int _thread_count;//从属线程的数量
    std::vector<LoopThread*> _threads;//从属线程池
    int _next_loop_idx;//选择一个eventloop
    std::vector<EventLoop*> _loops;//分配多个从属线程的loop
public:
    LoopThreadPool(EventLoop*baseloop):_baseloop(baseloop),_thread_count(0),_next_loop_idx(0){}

    //设置线程数量
    void SetThreadCount(int thread_count){
         _thread_count=thread_count;
    }

    //创建EventThread
    void Create(){
        if(_thread_count>0){
            _threads.resize(_thread_count);
            for(int i=0;i<_thread_count;i++){
                _threads[i]=new LoopThread();
                _loops.push_back(_threads[i]->GetLoop());
            }
        }
    }
    //线程分配
    EventLoop* GetLoop(){
        if(_thread_count==0){
            return _baseloop;
        }
        // _next_loop_idx++;
        // return _loops[_next_loop_idx%_thread_count];
        _next_loop_idx=(_next_loop_idx+1)%_thread_count;
        return _loops[_next_loop_idx];
    }

    // void Init(PtrConnection& new_conn){
    //     new_conn->EnableInactiveRelease(10);
    //     new_conn->Established();
    // }
};












typedef enum
{
    DISCONNECTED,  //--连接关闭状态
    CONNECTING,   //.-连接建立成功-待处理状态
    CONNECTED,    //--连接建立完成，各种设置已完成，可以通信的状态;
    DISCONNECTING //--待关闭状态
} ConnStatu;

class Any
{
};

class Connection;
using PtrConnection = std::shared_ptr<Connection>;

class Connection:public std::enable_shared_from_this<Connection>//内部生成有weak_ptr，可以根据这个生成shared_ptr
{
private:
    uint64_t _conn_id; // 连接唯一ID
    // uint64_t _timer_id; //定时器ID，必须是唯一的，这块为了简化操作使用conn_id作为定时器ID
    int _sockfd;                       // 套接字ID
    Socket _socket;                    // 管理套接字
    bool _enable_inactive_release;     // 连接是否启动非活跃销毁的判断标志，默认为false
    EventLoop *_loop;                  // 连接所关联的一个EventLoop
    ConnStatu _statu;                        // 连接状态
    std::shared_ptr<Channel> _channel; // 监控套接字
    Buffer _in_buffer;                 // 输入缓冲区——存放从socket中读取到的数据
    Buffer _out_buffer;                // 输出缓冲区——写事件触发后向对端发送的数据
    Any _context;                      // 请求的接收处理连接上下文
    using ConnectedCallback = std::function<void(const PtrConnection &)>;               // 连接事件到来后的回调函数
    using MessageCallback = std::function<void(const PtrConnection &, Buffer *)>; // 数据到来后的回调函数
    using ClosedCallback = std::function<void(const PtrConnection &)>;            // 关闭事件到来后的回调函数
    using AnyEventCallback = std::function<void(const PtrConnection &)>;          // 任意事件到来后的回调函数
    ConnectedCallback _connected_callback;
    MessageCallback _message_callback;
    ClosedCallback _closed_callback;
    AnyEventCallback _event_callback;
    ClosedCallback _server_close_callback;
private:
    void HandleRead(){
        char buffer[65536];
        int re=_socket.NonBlockRecv(buffer,65535);
        if(re<0){
           return ShutdownInLoop();
        }
        _in_buffer.WriteAndPush(buffer,re);
        //DEBUG("recv data:%d",re);
        if(_in_buffer.ReadAbleSize()>0){
            //DEBUG_LOG("recv data:%d",re);
            _message_callback(shared_from_this(),&_in_buffer);
        }
    }

    void HandleWrite(){
        // int len=_out_buffer.ReadAbleSize();
        // std::string data=_out_buffer.ReadAsStringAndPop(len);
        // DEBUG_LOG("ReadAbleSize:%d",_out_buffer.ReadAbleSize());
        // _socket.NonBlockSend((void*)data.c_str(),data.size());
        // _channel->DisableWrite();

        ssize_t ret = _socket.NonBlockSend(_out_buffer.ReadPosition(), _out_buffer.ReadAbleSize());
        if (ret < 0) {
            //发送错误就该关闭连接了，
            if (_in_buffer.ReadAbleSize() > 0) {
                _message_callback(shared_from_this(), &_in_buffer);
            }
            return ReleaseInLoop();//这时候就是实际的关闭释放操作了。
        }
        _out_buffer.MoveReadOffset(ret);//千万不要忘了，将读偏移向后移动
        if (_out_buffer.ReadAbleSize() == 0) {
            _channel->DisableWrite();// 没有数据待发送了，关闭写事件监控
            //如果当前是连接待关闭状态，则有数据，发送完数据释放连接，没有数据则直接释放
            if (_statu == DISCONNECTING) {
                return ReleaseInLoop();
            }
        }
        return;
    }

    void HandleEvent(){
        _loop->TimerRefresh(_conn_id);
    }

    // 连接建立就绪后，进行的一系列操作
    void EstablishedInLoop(){
        _channel->EnableRead();
        _statu=CONNECTED;
        if(_connected_callback) _connected_callback(shared_from_this());
    }

    // 发送数据，将数据放到发送缓冲区，启动写事件监控               
    void SendInLoop(Buffer buf){
        _out_buffer.WriteBufferAndPush(buf);
        _channel->EnableWrite();
    }
    // //服务器释放对connection的管理
    void ReleaseInLoop(){
        //DEBUG_LOG("USing ReleaseInLoop:%s",this);
        _statu=DISCONNECTED;
        _channel->Remove();
        //_channel->DisTriggerAl1();
        _socket.Close();
        //注意调用顺序
        if (_loop->HasTimer(_conn_id)) CancelInactiveReleaseInLoop();
        //if(_loop->HasTimer(_conn_id)) _loop->TimerCancel(_conn_id);//任务取消
        if(_closed_callback) _closed_callback(shared_from_this());
        if(_server_close_callback) _server_close_callback(shared_from_this());
     }

//这个接口才是实际的释放接口
        // void ReleaseInLoop() {
        //     //1. 修改连接状态，将其置为DISCONNECTED
        //     _statu = DISCONNECTED;
        //     //2. 移除连接的事件监控
        //     _channel->Remove();
        //     //3. 关闭描述符
        //     _socket.Close();
        //     //4. 如果当前定时器队列中还有定时销毁任务，则取消任务
        //     if (_loop->HasTimer(_conn_id)) CancelInactiveReleaseInLoop();
        //     //5. 调用关闭回调函数，避免先移除服务器管理的连接信息导致Connection被释放，再去处理会出错，因此先调用用户的回调函数
        //     if (_closed_callback) _closed_callback(shared_from_this());
        //     //移除服务器内部管理的连接信息
        //     if (_server_close_callback) _server_close_callback(shared_from_this());
        // }

    // 提供给组件使用者的关闭接口--并不实际关闭，需要判断有没有数据待处理
    void ShutdownInLoop(){
        //设置标志，后续判断缓冲区里没有数据时直接关闭
        _statu=DISCONNECTING;
        if(_in_buffer.ReadAbleSize()>0){
            if(_message_callback) _message_callback(shared_from_this(),&_in_buffer);
        }
        if(_out_buffer.ReadAbleSize()>0){
            if(_channel->WriteAble()==false){
                _channel->EnableWrite();
            }
        }
        //DEBUG_LOG("Shutdown ReadAbleSize:%d",_out_buffer.ReadAbleSize());
        if(_out_buffer.ReadAbleSize()==0){
            ReleaseInLoop();
        }
    }                   
    // 启动非活跃销毁，并定义多长时间无通信就是非活跃，添加定时任务
    void EnableInactiveReleaseInLoop(int sec){
        _loop->TimerAdd(_conn_id,sec,std::bind(&Connection::ShutdownInLoop,this));
    } 
    // 取消非活跃销毁
    void CancelInactiveReleaseInLoop(){
        _loop->TimerCancel(_conn_id);
    }        
    //切换协议---重置上下文以及阶段性处理函数
    void UpgradeInLoop(const Any &context, const ConnectedCallback &conn, const MessageCallback &msg,
                       const ClosedCallback &closed, const AnyEventCallback &event){
                        _context=context;
                        _connected_callback=conn;
                        _message_callback=msg;
                        _closed_callback=closed;
                        _event_callback=event;
                       }

public:
    Connection(EventLoop *loop, uint64_t conn_id, int sockfd)
        : _conn_id(conn_id), _sockfd(sockfd),_socket(_sockfd),_loop(loop), _statu(DISCONNECTED), _channel(new Channel(_loop,_sockfd))
    {
        _channel->SetReadCallback(std::bind(&Connection::HandleRead,this));
        _channel->SetWriteCallback(std::bind(&Connection::HandleWrite,this));
        _channel->SetErrorCallback(std::bind(&Connection::Shutdown,this));
        _channel->SetCloseCallback(std::bind(&Connection::Shutdown,this));
        _channel->SetEventCallback(std::bind(&Connection::HandleEvent,this));//任意事件回调都需要刷新时间
    }

    ~Connection(){
        DEBUG_LOG("RELEASE CONNECTION:%p:",this);
    }

    uint64_t Id(){
        return _conn_id;
    }

    int Fd(){
        return _sockfd;
    }

    bool EnableInactiveRelease(){
        return _enable_inactive_release;
    }

    bool StatuIsCONNECTED(){
        return _statu == CONNECTED;
    }

    void SetContext(const Any &context){
        _context = context;
    }

    Any *GetContext(){
        return &_context;
    }

    Connection* Get(){
        return this;
    }

    Buffer* InBuffer(){
        return &_in_buffer;
    }

    Buffer* OutBuffer(){
        return &_out_buffer;
    }

    void SetConnectedCallback(const ConnectedCallback &conn){_connected_callback=conn;}
    void SetMessageCallback(const MessageCallback &msg) {_message_callback=msg;}
    void SetClosedCallback(const ClosedCallback &closed) {_closed_callback=closed;}
    void SetAnyEventCallback(const AnyEventCallback &event) {_event_callback=event;}
    void SetServerClosedCallback(const ClosedCallback &closed) {_server_close_callback=closed;}               
    // 连接建立就绪后，进行的一系列操作
    void Established()
    {
        _loop->RunInLoop((std::bind(&Connection::EstablishedInLoop, this)));
    }
    // 发送数据，将数据放到发送缓冲区，启动写事件监控
    void Send(char *data, size_t len)
    {
        //外界传入的data，可能是个临时的空间，我们现在只是把发送操作压入了任务池，有可能并没有被立即执行
        //因此有可能执行的时候，data指向的空间有可能已经被释放了。
        Buffer buf;
        buf.WriteAndPush(data,len);
        //_loop->RunInLoop(std::bind(&Connection::SendInLoop, this, data, len));
        _loop->RunInLoop(std::bind(&Connection::SendInLoop, this, buf));

    }
    // 提供给组件使用者的关闭接口--并不实际关闭，需要判断有没有数据待处理
    void Shutdown()
    {
        _loop->RunInLoop(std::bind(&Connection::ShutdownInLoop, this));
    }
    // 启动非活跃销毁，并定义多长时间无通信就是非活跃，添加定时任务
    void EnableInactiveRelease(int sec)
    {
        _loop->RunInLoop(std::bind(&Connection::EnableInactiveReleaseInLoop, this, sec));
    }
    // 取消非活跃销毁
    void CancelInactiveRelease()
    {
        _loop->RunInLoop(std::bind(&Connection::CancelInactiveReleaseInLoop, this));
    }
    // 切换协议---重置上下文以及阶段性处理函数
    void Upgrade(const Any &context, const ConnectedCallback &conn, const MessageCallback &msg,
                 const ClosedCallback &closed, const AnyEventCallback &event){
        _loop->RunInLoop(std::bind(&Connection::UpgradeInLoop, this,context, conn, msg,closed,event));
    }
};





















class Acceptor{
private:
    Socket _lst_sock;
    int _listen_fd;
    EventLoop* _loop;
    std::shared_ptr<Channel> _channel;
    using AcceptorCallback=std::function<void(int)>;
    AcceptorCallback _acceptor_cb;
public:
    //有新连接到来后的回调处理
    void HandleRead(){
        //int fd=_channel->Fd();
        //DEBUG_LOG("等待连接中");
        int newfd=accept(_listen_fd,nullptr,nullptr);
        if(newfd<0){
            ERR_LOG("ACCEPT FAIL:%s",strerror(newfd));
            std::cout<<"accept 错误"<<std::endl;
            return ;
        }
        //DEBUG_LOG("out new connection:%d",newfd);
        if(_acceptor_cb)
            //DEBUG_LOG("in new connection:%d",newfd);
            _acceptor_cb(newfd);
    }

    int CreateServer(int port){
        if(_lst_sock.CreateServer(port)==false){
            DEBUG_LOG("CreateServer FAIL");
            exit(-1);
        }

        return _lst_sock.Fd();
    }
public:
    Acceptor(EventLoop* loop,int port)
    :_listen_fd(CreateServer(port))
    ,_loop(loop)
    ,_channel(new Channel(_loop,_listen_fd))
    {
        //Init();
    }

    ~Acceptor(){
        _lst_sock.Close();
    }
    //设置回调函数，启动读事件监控
    void Init(){
        _channel->SetReadCallback(std::bind(&Acceptor::HandleRead,this));
        _channel->EnableRead();
        //DEBUG_LOG("Init");
    }

    //设置新连接建立后的回调函数
    void SetAcceptorCallback(const AcceptorCallback& cb){
        _acceptor_cb=cb;
    }
};












class TcpServer{
private:
    int _conn_id;
    std::unordered_map<int,PtrConnection> _conns;
    EventLoop _baseloop;
    Acceptor _acceptor;
    LoopThreadPool _pool;
    Any _context;
    int _sec;
    using ConnectedCallback = std::function<void(const PtrConnection &)>;               // 连接事件到来后的回调函数
    using MessageCallback = std::function<void(const PtrConnection &, Buffer *)>; // 数据到来后的回调函数
    using ClosedCallback = std::function<void(const PtrConnection &)>;            // 关闭事件到来后的回调函数
    using AnyEventCallback = std::function<void(const PtrConnection &)>;          // 任意事件到来后的回调函数
    ConnectedCallback _connected_callback;
    MessageCallback _message_callback;
    ClosedCallback _closed_callback;
    AnyEventCallback _event_callback;
    ClosedCallback _server_close_callback;

private:
    void NewConnection(int newfd){
        _conn_id++;
        PtrConnection new_conn(new Connection(_pool.GetLoop(),_conn_id,newfd));
        new_conn->SetMessageCallback(_message_callback);
        new_conn->SetClosedCallback(_closed_callback);
        new_conn->SetConnectedCallback(_connected_callback);
        if(_sec>0) new_conn->EnableInactiveRelease(_sec);
        new_conn->Established();
        _conns.insert(std::make_pair(_conn_id,new_conn));
    }

    //切换协议---重置上下文以及阶段性处理函数
    void UpgradeInLoop(const Any &context, const ConnectedCallback &conn, const MessageCallback &msg,
                       const ClosedCallback &closed, const AnyEventCallback &event){
                        _context=context;
                        _connected_callback=conn;
                        _message_callback=msg;
                        _closed_callback=closed;
                        _event_callback=event;
                       }
public:
    TcpServer(int port):_conn_id(0),_acceptor(&_baseloop,port),_pool(&_baseloop),_sec(0){
        //先设置读事件回调函数再启动读监控
        _acceptor.SetAcceptorCallback(std::bind(&TcpServer::NewConnection,this,std::placeholders::_1));
    }

    //设置回调函数
    void SetConnectedCallback(const ConnectedCallback &conn){_connected_callback=conn;}
    void SetMessageCallback(const MessageCallback &msg) {_message_callback=msg;}
    void SetClosedCallback(const ClosedCallback &closed) {_closed_callback=closed;}
    void SetAnyEventCallback(const AnyEventCallback &event) {_event_callback=event;}
    void SetServerClosedCallback(const ClosedCallback &closed) {_server_close_callback=closed;}  
    //开启监听套接字监控
    void Start(){
        _acceptor.Init();
        _baseloop.Start();
        }
    //设置Loop线程池数量
    void SetThreadCount(int thread_count){_pool.SetThreadCount(thread_count);}
    void CreateTHreadPool(){_pool.Create();};
    //启动非活跃销毁
    void EnableInactiveRelease(int sec){
        _sec=sec;
    }
    //取消非活跃销毁
    void CancelRelease(){
        
    }

    //切换协议
    void Upgrade(const Any &context, const ConnectedCallback &conn, const MessageCallback &msg,
                 const ClosedCallback &closed, const AnyEventCallback &event){
        _baseloop.RunInLoop(std::bind(&TcpServer::UpgradeInLoop, this,context, conn, msg,closed,event));
    }
};



void Channel::Remove() { return _loop->RemoveEvent(this); }
void Channel::Update() { return _loop->UpdateEvent(this); }
bool TimerWheel::TimerIsInLoop() { return _loop->IsInLoop(); }
void TimerWheel::TimerQueueInLoop(std::function<void()> fc) { _loop->QueueInLoop(fc);}


class NetWork {
    public:
        NetWork() {
            DEBUG_LOG("SIGPIPE INIT");
            signal(SIGPIPE, SIG_IGN);
        }
};
static NetWork nw;
#endif